package layers.agents;

import java.util.ArrayList;

import layers.physical.Crossroad;
import layers.physical.Path;
import layers.physical.Truck;

import commands.EnterCrossroadCommand;
import commands.MoveForwardCommand;

import framework.layer.agent.Agent;

public class TruckAgent extends Agent implements AgentInterface {

	private Crossroad lastCr = null;
	private PackageAgent packageAgent;
	private TruckAgentState state;
	private Truck truck;
	private ArrayList<Path> paths;
	private Path intention;

	public TruckAgent() {
		this.state = new TruckAgentStateCreatingIntention(this);
		this.paths = new ArrayList<Path>();
	}

	protected void clearPackageAgent() {
		this.packageAgent = null;
	}

	protected void dropPackage(){
		this.getState().dropPackage();
	}

	protected void dropPackageCallback() {
		this.clearPackageAgent();
	}

	@Override
	public void executeDeploymentOptions() {
	}

	protected PackageAgent getPackageAgent() {
		return this.packageAgent;
	}

	private TruckAgentState getState(){
		return this.state;
	}

	@Override
	public void processTick(long timePassed) {
		if (truck == null)
			truck = (Truck) this.getDevice().getPhysicalEntity();
		this.getState().processTick();
	}

	private void setPackageAgent(PackageAgent agent) {
		if(agent == null)
			throw new IllegalArgumentException("Package agent cannot be null.");
		this.packageAgent = agent;
	}

	protected void setState(TruckAgentState state) {
		this.state = state;
	}

	protected Truck getTruck() {
		return this.truck;
	}

	protected Crossroad getLastCr() {
		return this.lastCr;
	}

	protected void setLastCr(Crossroad crossroad) {
		if(crossroad == null)
			throw new IllegalArgumentException("Crossroad cannot be null.");
		this.lastCr = crossroad;
	}


	public void rejectIntention(Path path) {
		this.getState().rejectIntention(path);
	}

	protected Path getBestPath() {
		Path result = null;
		for(Path path : this.paths){
			if(path.index != 0)
				System.out.println("illegal index");
			if(result == null)
				result = path;
			long resultTotalDist = result.getTotalDistance();
			long pathTotalDist = path.getTotalDistance();
			if(resultTotalDist > pathTotalDist)
				result = path;
		}
		return result;
	}

	public void confirmIntention(Path path) {
		this.getState().confirmIntention(path);
	}

	public boolean hasIntention() {
		return this.intention != null;
	}

	public void addPath(Path path) {
		paths.add(path);		
	}

	public ArrayList<Path> getPaths(){
		return paths;
	}

	public void deleteAllPaths(){
		paths = new ArrayList<Path>();
	}

	public String toString(){
		return ""+this.getTruck().getId();
	}

	public void clearPaths() {
		this.paths = new ArrayList<Path>();
	}

	protected void ensureIsOnCrossRoad() {
		if(this.getTruck().allCommandsProcessed()){
			if(this.getTruck().isOnConnection() && !this.getTruck().getConnectionPosition().getConnection().isAtEnd(this.getTruck())){
				this.getTruck().addCommand(new MoveForwardCommand(this.getTruck()), this);
			}else if (this.getTruck().isOnConnection() && this.getTruck().getConnectionPosition().getConnection().isAtEnd(this.getTruck())){
				this.getTruck().addCommand(new EnterCrossroadCommand(this.getTruck()), this);
			}
		}
	}

	protected void addPackage(PackageAgent packageAgent) {
		setPackageAgent(packageAgent);
	}
}
